package main

import (
	"fmt"
)

/*
	Golang中没有异常机制
	使用panic/recover模式来处理错误
	panic可以在任何地方引发
	recover只能在defer调用的函数中有效
*/

func fn1() {
	fmt.Println("fn1")
}

func fn2() {
	panic("抛出一个异常")
}

func fn3() {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Printf("异常信息为:%v 类型为:%T\n", err, err)
		}
	}()
	panic("抛出一个异常")
}

func calc1(a int, b int) int {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println(err)
		}
	}()
	return a / b
}

func readFile(fileName string) error {
	if fileName == "main.go" {
		return nil
	} else {
		return fmt.Errorf("读取文件%v失败", fileName)
	}
}

func myFn(filename string) {
	defer func() {
		e := recover()
		if e != nil {
			fmt.Println(e)
			fmt.Println("发送错误邮件")
		}
	}()
	err := readFile(filename)
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("读取文件%v成功\n", filename)
	}
}

func main() {

	// // 只使用panic会中断程式
	// fn1()
	// fn2()
	// fmt.Println("结束")

	// 使用recover可以接受panic抛出的异常，不中断程式
	// fn1()
	// fn3()
	// fmt.Println("结束")

	// // 例子
	// // defer func() {
	// // 	err := recover()
	// // 	if err != nil {
	// // 		fmt.Println(err)
	// // 	}
	// // }()
	// fmt.Print(calc1(10, 0))

	// 主动抛出异常
	myFn("main.go")
	myFn("main2.go")
	fmt.Println("结束")

}
